﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        private Point _origin;  // 平移起点
        private Point _start;   // 鼠标按下时的位置
        private double _scale = 1.0;  // 当前缩放比例
        private Point _manipulationOrigin; // Manipulation 操作起点

        public MainWindow()
        {
            InitializeComponent();

            // 启用触摸操作
            this.TouchDown += MainWindow_TouchDown;

            // 加载示例图片（可以替换为你自己的图片路径）
            //try
            //{
            //    image.Source = new System.Windows.Media.Imaging.BitmapImage(
            //        new Uri("pack://application:,,,/Resources/sample.jpg"));
            //}
            //catch
            //{
            //    // 如果图片加载失败，使用一个简单的矩形代替
            //    var drawingVisual = new DrawingVisual();
            //    using (var drawingContext = drawingVisual.RenderOpen())
            //    {
            //        drawingContext.DrawRectangle(Brushes.LightBlue, null,
            //            new Rect(0, 0, 800, 600));
            //        drawingContext.DrawText(
            //            new FormattedText("Placeholder Image",
            //                System.Globalization.CultureInfo.CurrentCulture,
            //                FlowDirection.LeftToRight,
            //                new Typeface("Arial"),
            //                32, Brushes.Black, 1.0),
            //            new Point(50, 50));
            //    }
            //    var bitmap = new RenderTargetBitmap(800, 600, 96, 96, PixelFormats.Pbgra32);
            //    bitmap.Render(drawingVisual);
            //    image.Source = bitmap;
            //}
        }

        #region 触摸和鼠标事件处理
        private void MainWindow_TouchDown(object sender, TouchEventArgs e)
        {
            // 确保触摸事件能够被正确处理
            e.TouchDevice.Capture(grid);
        }

        private void Grid_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
        {
            // 设置 Manipulation 模式
            e.Mode = ManipulationModes.Scale | ManipulationModes.Translate;
            e.Handled = true;
            //_manipulationOrigin = translateTransform.Value;
        }

        private void Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            // 处理缩放
            if (e.DeltaManipulation.Scale.X != 0 || e.DeltaManipulation.Scale.Y != 0)
            {
                Point center = e.ManipulationOrigin;
                double scaleFactor = (e.DeltaManipulation.Scale.X + e.DeltaManipulation.Scale.Y) / 2;
                Zoom(center, scaleFactor);
            }

            // 处理平移
            Vector translation = e.DeltaManipulation.Translation;
            if (translation.X != 0 || translation.Y != 0)
            {
                double newX = translateTransform.X + translation.X;
                double newY = translateTransform.Y + translation.Y;

                // 应用边界限制
                ApplyTranslationBounds(ref newX, ref newY);

                translateTransform.X = newX;
                translateTransform.Y = newY;
            }

            e.Handled = true;
        }

        private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            // 获取鼠标相对于Image的位置
            Point mousePos = e.GetPosition(image);

            // 计算缩放因子 (10% per wheel click)
            double zoomFactor = 1.1;
            if (e.Delta < 0)
            {
                zoomFactor = 1 / zoomFactor;
            }

            // 执行缩放
            Zoom(mousePos, zoomFactor);

            e.Handled = true;
        }

        private void ScrollViewer_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // 开始平移
            var mousePos = e.GetPosition(scrollViewer);
            if (mousePos.X <= scrollViewer.ViewportWidth &&
                mousePos.Y <= scrollViewer.ViewportHeight)
            {
                _start = e.GetPosition(scrollViewer);
                _origin = new Point(translateTransform.X, translateTransform.Y);
                scrollViewer.Cursor = Cursors.Hand;
                scrollViewer.CaptureMouse();
            }

            e.Handled = true;
        }

        private void ScrollViewer_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            // 执行平移
            if (scrollViewer.IsMouseCaptured)
            {
                Point currentPos = e.GetPosition(scrollViewer);
                double newX = _origin.X + (currentPos.X - _start.X);
                double newY = _origin.Y + (currentPos.Y - _start.Y);

                // 应用边界限制
                ApplyTranslationBounds(ref newX, ref newY);

                translateTransform.X = newX;
                translateTransform.Y = newY;
            }

            e.Handled = true;
        }

        private void ScrollViewer_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // 结束平移
            scrollViewer.ReleaseMouseCapture();
            scrollViewer.Cursor = Cursors.Arrow;

            e.Handled = true;
        }
        #endregion

        #region 缩放和平移功能
        private void Zoom(Point mousePos, double zoomFactor)
        {
            // 计算新的缩放比例
            double newScale = _scale * zoomFactor;

            // 限制缩放范围
            const double MinScale = 0.1;
            const double MaxScale = 10.0;
            newScale = Math.Max(MinScale, Math.Min(MaxScale, newScale));

            // 计算缩放前后的坐标转换
            Vector relative = mousePos - new Point(translateTransform.X, translateTransform.Y);
            Vector delta = (relative * zoomFactor) - relative;

            // 计算新的平移位置
            double newX = translateTransform.X - delta.X;
            double newY = translateTransform.Y - delta.Y;

            // 应用边界限制
            ApplyTranslationBounds(ref newX, ref newY, newScale);

            // 应用变换
            scaleTransform.ScaleX = newScale;
            scaleTransform.ScaleY = newScale;
            translateTransform.X = newX;
            translateTransform.Y = newY;

            _scale = newScale;
        }

        // 应用平移边界限制
        //private void ApplyTranslationBounds(ref double newX, ref double newY, double? scale = null)
        //{
        //    Rect imageBounds = GetImageBounds(scale);
        //    Rect viewportBounds = new Rect(0, 0, scrollViewer.ViewportWidth, scrollViewer.ViewportHeight);

        //    // 限制X轴平移
        //    if (imageBounds.Width > viewportBounds.Width)
        //    {
        //        newX = Math.Min(0, newX); // 不能向右超出边界
        //        newX = Math.Max(viewportBounds.Width - imageBounds.Width, newX); // 不能向左超出边界
        //    }
        //    //else
        //    //{
        //    //    newX = (viewportBounds.Width - imageBounds.Width) / 2; // 居中对齐
        //    //}

        //    // 限制Y轴平移
        //    if (imageBounds.Height > viewportBounds.Height)
        //    {
        //        newY = Math.Min(0, newY); // 不能向下超出边界
        //        newY = Math.Max(viewportBounds.Height - imageBounds.Height, newY); // 不能向上超出边界
        //    }
        //    //else
        //    //{
        //    //    newY = (viewportBounds.Height - imageBounds.Height) / 2; // 居中对齐
        //    //}
        //}
        private void ApplyTranslationBounds(ref double newX, ref double newY, double? scale = null)
        {
            double actualScale = scale ?? _scale;
            double scaledWidth = image.ActualWidth * actualScale;
            double scaledHeight = image.ActualHeight * actualScale;

            double viewportWidth = scrollViewer.ViewportWidth;
            double viewportHeight = scrollViewer.ViewportHeight;

            // X轴边界检查
            if (scaledWidth > viewportWidth)
            {
                // 图像比视口宽，限制左右边界
                newX = Math.Min(0, newX); // 不能右移超出边界
                newX = Math.Max(viewportWidth - scaledWidth, newX); // 不能左移超出边界
                Console.WriteLine("超出");
            }
            else
            {
                // 图像比视口窄，居中显示
                newX = (viewportWidth - scaledWidth) / 2;
                Console.WriteLine("居中");
            }

            // Y轴边界检查
            if (scaledHeight > viewportHeight)
            {
                // 图像比视口高，限制上下边界
                newY = Math.Min(0, newY); // 不能下移超出边界
                newY = Math.Max(viewportHeight - scaledHeight, newY); // 不能上移超出边界
            }
            else
            {
                // 图像比视口矮，居中显示
                newY = (viewportHeight - scaledHeight) / 2;
            }
        }
        // 获取当前图像边界（考虑缩放）
        private Rect GetImageBounds(double? scale = null)
        {
            double actualScale = scale ?? _scale;
            double width = image.ActualWidth * actualScale;
            double height = image.ActualHeight * actualScale;
            return new Rect(0, 0, width, height);
        }

        private void ZoomIn_Click(object sender, RoutedEventArgs e)
        {
            // 以图像中心为基准放大
            Zoom(new Point(image.ActualWidth / 2, image.ActualHeight / 2), 1.2);
        }

        private void ZoomOut_Click(object sender, RoutedEventArgs e)
        {
            // 以图像中心为基准缩小
            Zoom(new Point(image.ActualWidth / 2, image.ActualHeight / 2), 1 / 1.2);
        }

        private void Reset_Click(object sender, RoutedEventArgs e)
        {
            // 重置缩放和平移
            _scale = 1.0;
            scaleTransform.ScaleX = 1.0;
            scaleTransform.ScaleY = 1.0;

            // 计算居中位置
            Rect imageBounds = GetImageBounds();
            Rect viewportBounds = new Rect(0, 0, scrollViewer.ViewportWidth, scrollViewer.ViewportHeight);

            translateTransform.X = (viewportBounds.Width - imageBounds.Width) / 2;
            translateTransform.Y = (viewportBounds.Height - imageBounds.Height) / 2;
        }
        #endregion
    }
}